﻿Imports System
Imports System.Collections.Generic
Imports System.ComponentModel.Design
Imports System.IO
Imports System.Reflection

Namespace System.Workflow.ComponentModel.Compiler
    Friend Class AssemblyLoader
        ' Methods
        Friend Sub New(ByVal typeProvider As TypeProvider, ByVal filePath As String)
            Me.isLocalAssembly = False
            Me.typeProvider = typeProvider
            If Not File.Exists(filePath) Then
                Throw New FileNotFoundException
            End If
            Dim assemblyName As AssemblyName = Nothing
            If (String.Compare(filePath, GetType(Object).Assembly.Location, StringComparison.OrdinalIgnoreCase) = 0) Then
                assemblyName = GetType(Object).Assembly.GetName
            Else
                assemblyName = AssemblyName.GetAssemblyName(filePath)
            End If
            Dim service As ITypeResolutionService = DirectCast(typeProvider.GetService(GetType(ITypeResolutionService)), ITypeResolutionService)
            If ((Not service Is Nothing) AndAlso (Not assemblyName Is Nothing)) Then
                Try 
                    Me.assembly = service.GetAssembly(assemblyName)
                    If ((((Me.assembly Is Nothing) AndAlso (Not assemblyName.GetPublicKeyToken Is Nothing)) AndAlso ((assemblyName.GetPublicKeyToken.GetLength(0) = 0) AndAlso (Not assemblyName.GetPublicKey Is Nothing))) AndAlso (assemblyName.GetPublicKey.GetLength(0) = 0)) Then
                        assemblyName.SetPublicKey(Nothing)
                        assemblyName.SetPublicKeyToken(Nothing)
                        Me.assembly = service.GetAssembly(assemblyName)
                    End If
                Catch obj1 As Object
                End Try
            End If
            If ((Me.assembly Is Nothing) AndAlso (Not assemblyName Is Nothing)) Then
                Try 
                    Me.assembly = Assembly.Load(assemblyName)
                Catch obj2 As Object
                End Try
            End If
            If (Me.assembly Is Nothing) Then
                Me.assembly = Assembly.LoadFrom(filePath)
            End If
        End Sub

        Friend Sub New(ByVal typeProvider As TypeProvider, ByVal [assembly] As Assembly, ByVal isLocalAssembly As Boolean)
            Me.isLocalAssembly = isLocalAssembly
            Me.typeProvider = typeProvider
            Me.assembly = [assembly]
        End Sub

        Friend Function [GetType](ByVal typeName As String) As Type
            If (Not Me.assembly Is Nothing) Then
                Dim type As Type = Nothing
                Try 
                    type = Me.assembly.GetType(typeName)
                Catch exception1 As ArgumentException
                End Try
                If ((Not type Is Nothing) AndAlso ((type.IsPublic OrElse type.IsNestedPublic) OrElse (Me.isLocalAssembly AndAlso (type.Attributes <> TypeAttributes.NestedPrivate)))) Then
                    Return type
                End If
            End If
            Return Nothing
        End Function

        Friend Function GetTypes() As Type()
            Dim list As New List([Of] Type)
            If (Not Me.assembly Is Nothing) Then
                Dim type As Type
                For Each type In Me.assembly.GetTypes
                    If (type.IsPublic OrElse (Me.isLocalAssembly AndAlso (type.Attributes <> TypeAttributes.NestedPrivate))) Then
                        list.Add(type)
                    End If
                Next
            End If
            Return list.ToArray
        End Function


        ' Properties
        Friend ReadOnly Property [Assembly] As Assembly
            Get
                Return Me.assembly
            End Get
        End Property

        Friend ReadOnly Property AssemblyName As AssemblyName
            Get
                If (Me.assemblyName Is Nothing) Then
                    Me.assemblyName = Me.assembly.GetName(True)
                End If
                Return Me.assemblyName
            End Get
        End Property


        ' Fields
        Private [assembly] As Assembly
        Private assemblyName As AssemblyName
        Private isLocalAssembly As Boolean
        Private typeProvider As TypeProvider
    End Class
End Namespace

